﻿using Fineout.ConfigShellSettings.Environment.Configuration;
using JetBrains.Annotations;
using Orchard.Environment;
using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.AppData;
using Orchard.Logging;

namespace Fineout.ConfigShellSettings
{
    [UsedImplicitly]
    public class DefaultConfigShellSettingsUpdater : IFeatureEventHandler
    {
        //TODO: Remove hardcoding
        private const string FeatureId = "Fineout.ConfigShellSettings";
        private readonly IAppDataFolder _appDataFolder;
        private readonly IShellSettingsManagerEventHandler _events;
        private readonly IShellSettingsManager _shellSettingsManager;

        #region Constructor

        public DefaultConfigShellSettingsUpdater(
            IAppDataFolder appDataFolder,
            IShellSettingsManagerEventHandler events,
            IShellSettingsManager shellSettingsManager)
        {
            _appDataFolder = appDataFolder;
            _events = events;
            _shellSettingsManager = shellSettingsManager;

            Logger = NullLogger.Instance;
        }

        #endregion Constructor

        public ILogger Logger { get; set; }

        #region IFeatureEventHandler Implementation

        void IFeatureEventHandler.Enabling(Feature feature)
        {
            if (feature.Descriptor.Id != FeatureId)
                return;

            // Set Web.config AppSettings from existing Orchard shell settings
            SaveConfigSettingsFromShellSettings();

            // Enable ConfigShellSettingsManager
            HostConfigManager.EnableConfigShellSettings();
        }

        void IFeatureEventHandler.Disabling(Feature feature)
        {
            if (feature.Descriptor.Id != FeatureId)
                return;

            // Set Orchard shell settings (Settings.txt) from existing Web.config AppSettings
            SaveShellSettingsFromConfigSettings();

            // Disable ConfigShellSettingsManager
            HostConfigManager.DisableConfigShellSettings();
        }

        #region Unused IFeatureEventHandler Methods

        void IFeatureEventHandler.Installing(Feature feature)
        {
        }

        void IFeatureEventHandler.Installed(Feature feature)
        {
        }

        void IFeatureEventHandler.Enabled(Feature feature)
        {
        }

        void IFeatureEventHandler.Disabled(Feature feature)
        {
        }

        void IFeatureEventHandler.Uninstalling(Feature feature)
        {
        }

        void IFeatureEventHandler.Uninstalled(Feature feature)
        {
        }

        #endregion IFeatureEventHandler Methods (not implemented)

        #endregion IFeatureEventHandler Implementation

        #region Private Helper Methods

        private void SaveConfigSettingsFromShellSettings()
        {
            // Ensure the IShellSettingsManager instance is of type ShellSettingsManager
            if (_shellSettingsManager.GetType() != typeof(ShellSettingsManager))
                return;

            // Load existing shell settings (Settings.txt) from ShellSettingsManager
            var settingsList = _shellSettingsManager.LoadSettings();

            // Save Web.config AppSettings for all existing shell settings
            var configSettingsManager = new ConfigShellSettingsManager(_appDataFolder, _events);
            foreach (var settings in settingsList)
            {
                configSettingsManager.SaveSettings(settings);
            }
        }

        private void SaveShellSettingsFromConfigSettings()
        {
            // Saving Web.config AppSettings implicitly saves Settings.txt as well
            var configSettingsManager = new ConfigShellSettingsManager(_appDataFolder, _events);
            var settingsList = configSettingsManager.LoadSettings();
            foreach (var settings in settingsList)
            {
                configSettingsManager.SaveSettings(settings);
            }
        }

        #endregion Private Helper Methods
    }
}
